package main

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"

	"golang.org/x/net/webdav" // 需在go.mod中添加依赖
)

var (
    currentDir = "./"
	webdavUser = "admin" // webdav用户名
	webdavPassword = "123456" // webdav密码
    password   = "123456" // 控制台密码
)

const port = 8000

func main() {
    http.HandleFunc("/webdav/control", func(resp http.ResponseWriter, req *http.Request) {
        resp.Header().Set("Content-Type", "text/html; charset=utf-8")
        fmt.Fprintln(resp, `
<!DOCTYPE html>
<html>
<head>
    <title>webdav控制页面</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
        :root {
            --main-bg: #181a1b;
            --panel-bg: #23272e;
            --accent: #4f8cff;
            --accent2: #007bff;
            --border: #333;
            --input-bg: #222325;
            --input-fg: #f1f1f1;
            --text: #e0e0e0;
            --text2: #b0b0b0;
            --danger: #c82333;
        }
        body {
            font-family: "Segoe UI", "Helvetica Neue", Arial, "Liberation Sans", sans-serif;
            margin: 0;
            padding: 0;
            background: linear-gradient(135deg, #232526 0%, #181a1b 100%);
            color: var(--text);
            min-height: 100vh;
        }
        header {
            text-align: center;
            margin-bottom: 20px;
            padding: 2.5rem 1rem 1.5rem 1rem;
            background: var(--panel-bg);
            border-bottom-left-radius: 30px;
            border-bottom-right-radius: 30px;
            box-shadow: 0 2px 12px #0004;
        }
        h1 {
            margin: 0;
            color: #fff;
            letter-spacing: 2px;
            font-size: 2.2rem;
        }
        section {
            background: var(--panel-bg);
            padding: 28px 24px 24px 24px;
            border-radius: 16px;
            box-shadow: 0 0 24px #000a;
            max-width: 520px;
            margin: -2rem auto 2rem auto;
        }
        label {
            display: block;
            margin-bottom: 10px;
            font-weight: bold;
            color: var(--accent);
            letter-spacing: 1px;
        }
        input[type="text"], input[type="password"] {
            width: calc(100% - 22px);
            padding: 10px;
            margin-bottom: 10px;
            border: 1.5px solid var(--border);
            border-radius: 6px;
            background: var(--input-bg);
            color: var(--input-fg);
            font-size: 1rem;
            transition: border 0.2s, box-shadow 0.2s;
        }
        input[type="text"]:focus, input[type="password"]:focus {
            border: 2px solid var(--accent);
            outline: none;
            box-shadow: 0 0 0 2px var(--accent2)33;
            background: #181a1b;
        }
        button {
            padding: 10px 18px;
            background: linear-gradient(90deg, var(--accent) 60%, var(--panel-bg) 100%);
            color: #fff;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-weight: bold;
            font-size: 1rem;
            transition: background 0.18s, transform 0.15s;
            box-shadow: 0 2px 8px var(--accent)33;
            margin-bottom: 0.5em;
        }
        button:hover {
            background: linear-gradient(90deg, var(--panel-bg) 60%, var(--accent) 100%);
            transform: translateY(-2px) scale(1.03);
        }
        #oneKeyBtn {
            background: linear-gradient(90deg, var(--accent2) 60%, var(--panel-bg) 100%);
            margin-bottom: 1.5em;
        }
        #oneKeyBtn:hover {
            background: linear-gradient(90deg, var(--panel-bg) 60%, var(--accent2) 100%);
        }
        #submitRes, #setWebdavPwdRes, #setConsolePwdRes, #setWebdavUserRes {
            margin-top: 10px;
            font-weight: bold;
            color: var(--accent);
            min-height: 1.2em;
        }
        #loginRes {
            color: var(--danger);
            min-height: 1.2em;
        }
        #loginBox {
            margin-bottom: 20px;
        }
        hr {
            border: none;
            border-top: 1px solid var(--border);
            margin: 2em 0;
        }
        ::selection {
            background: var(--accent2);
            color: #fff;
        }
        @media (max-width: 600px) {
            section {
                max-width: 98vw;
                padding: 1.2rem 0.7rem 1.2rem 0.7rem;
            }
            header {
                padding: 1.5rem 0.5rem 1rem 0.5rem;
            }
        }
    </style>
    <script>
        function showControl() {
            document.getElementById('loginBox').style.display = 'none';
            document.getElementById('controlBox').style.display = '';
            getCurrentDir();
            getWebdavUser();
            getWebdavPwd();
            getConsolePwd();
        }
        function login() {
            let infos = document.querySelectorAll('p');
            for (let info of infos) {
                info.textContent = '';
            }
            let pwd = document.getElementById('pwdInput').value;
            fetch('control/login', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ password: pwd })
            })
            .then(resp => resp.json())
            .then(json => {
                if(json.res === 'ok') {
                    showControl();
                } else {
                    document.getElementById('loginRes').textContent = json.res;
                }
            })
            .catch(err => document.getElementById('loginRes').textContent = '登录失败');
        }
        function getCurrentDir() {
            fetch('control/getDir', {
                headers: {
                    'X-Auth': sessionStorage.getItem('webdav_pwd') || ''
                }
            })
                .then(resp => {
                    if(resp.status === 401) {
                        document.getElementById('controlBox').style.display = 'none';
                        document.getElementById('loginBox').style.display = '';
                        document.getElementById('loginRes').textContent = '请重新登录';
                        return;
                    }
                    return resp.json();
                })
                .then(json => {
                    if(json && json.res !== undefined)
                        document.querySelector('#dirInput').value = json.res
                })
                .catch(err => document.querySelector('#submitRes').textContent = '获取当前webdav目录失败')
        }
        function submit() {
            let dir = document.querySelector('#dirInput').value
            fetch('control/setDir', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-Auth': sessionStorage.getItem('webdav_pwd') || ''
                },
                body: JSON.stringify({ dir: dir })
            })
                .then(resp => {
                    if(resp.status === 401) {
                        document.getElementById('controlBox').style.display = 'none';
                        document.getElementById('loginBox').style.display = '';
                        document.getElementById('loginRes').textContent = '请重新登录';
                        return;
                    }
                    return resp.json();
                })
                .then(json => {
                    if(json && json.res !== undefined) {
                        document.querySelector('#submitRes').textContent = json.res
                        getCurrentDir()
                    }
                })
                .catch(err => document.querySelector('#submitRes').textContent = '设置webdav目录失败')
        }
        function getWebdavUser() {
            fetch('control/getWebdavUser', {
                headers: {
                    'X-Auth': sessionStorage.getItem('webdav_pwd') || ''
                }
            })
            .then(resp => {
                if(resp.status === 401) {
                    document.getElementById('controlBox').style.display = 'none';
                    document.getElementById('loginBox').style.display = '';
                    document.getElementById('loginRes').textContent = '请重新登录';
                    return;
                }
                return resp.json();
            })
            .then(json => {
                if(json && json.res !== undefined)
                    document.querySelector('#webdavUserInput').value = json.res
            })
            .catch(err => document.querySelector('#setWebdavUserRes').textContent = '获取WebDAV用户名失败')
        }
        function setWebdavUser() {
            let user = document.querySelector('#webdavUserInput').value
            fetch('control/setWebdavUser', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-Auth': sessionStorage.getItem('webdav_pwd') || ''
                },
                body: JSON.stringify({ user: user })
            })
            .then(resp => {
                if(resp.status === 401) {
                    document.getElementById('controlBox').style.display = 'none';
                    document.getElementById('loginBox').style.display = '';
                    document.getElementById('loginRes').textContent = '请重新登录';
                    return;
                }
                return resp.json();
            })
            .then(json => {
                if(json && json.res !== undefined) {
                    document.querySelector('#setWebdavUserRes').textContent = json.res
                }
            })
            .catch(err => document.querySelector('#setWebdavUserRes').textContent = '设置WebDAV用户名失败')
        }
        function getWebdavPwd() {
            fetch('control/getWebdavPwd', {
                headers: {
                    'X-Auth': sessionStorage.getItem('webdav_pwd') || ''
                }
            })
            .then(resp => {
                if(resp.status === 401) {
                    document.getElementById('controlBox').style.display = 'none';
                    document.getElementById('loginBox').style.display = '';
                    document.getElementById('loginRes').textContent = '请重新登录';
                    return;
                }
                return resp.json();
            })
            .then(json => {
                if(json && json.res !== undefined)
                    document.querySelector('#webdavPwdInput').value = json.res
            })
            .catch(err => document.querySelector('#setWebdavPwdRes').textContent = '获取WebDAV密码失败')
        }
        function setWebdavPwd() {
            let pwd = document.querySelector('#webdavPwdInput').value
            fetch('control/setWebdavPwd', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-Auth': sessionStorage.getItem('webdav_pwd') || ''
                },
                body: JSON.stringify({ password: pwd })
            })
            .then(resp => {
                if(resp.status === 401) {
                    document.getElementById('controlBox').style.display = 'none';
                    document.getElementById('loginBox').style.display = '';
                    document.getElementById('loginRes').textContent = '请重新登录';
                    return;
                }
                return resp.json();
            })
            .then(json => {
                if(json && json.res !== undefined) {
                    document.querySelector('#setWebdavPwdRes').textContent = json.res
                }
            })
            .catch(err => document.querySelector('#setWebdavPwdRes').textContent = '设置WebDAV密码失败')
        }
        function getConsolePwd() {
            fetch('control/getConsolePwd', {
                headers: {
                    'X-Auth': sessionStorage.getItem('webdav_pwd') || ''
                }
            })
            .then(resp => {
                if(resp.status === 401) {
                    document.getElementById('controlBox').style.display = 'none';
                    document.getElementById('loginBox').style.display = '';
                    document.getElementById('loginRes').textContent = '请重新登录';
                    return;
                }
                return resp.json();
            })
            .then(json => {
                if(json && json.res !== undefined)
                    document.querySelector('#consolePwdInput').value = json.res
            })
            .catch(err => document.querySelector('#setConsolePwdRes').textContent = '获取控制台密码失败')
        }
        function setConsolePwd() {
            let pwd = document.querySelector('#consolePwdInput').value
            fetch('control/setConsolePwd', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-Auth': sessionStorage.getItem('webdav_pwd') || ''
                },
                body: JSON.stringify({ password: pwd })
            })
            .then(resp => {
                if(resp.status === 401) {
                    document.getElementById('controlBox').style.display = 'none';
                    document.getElementById('loginBox').style.display = '';
                    document.getElementById('loginRes').textContent = '请重新登录';
                    return;
                }
                return resp.json();
            })
            .then(json => {
                if(json && json.res !== undefined) {
                    document.querySelector('#setConsolePwdRes').textContent = json.res
                }
            })
            .catch(err => document.querySelector('#setConsolePwdRes').textContent = '设置控制台密码失败')
        }
        function oneKeySet() {
            document.getElementById('dirBtn').click();
            document.getElementById('webdavUserBtn').click();
            document.getElementById('webdavPwdBtn').click();
            document.getElementById('consolePwdBtn').click();
        }
        window.onload = function() {
            if(sessionStorage.getItem('webdav_pwd')) {
                showControl();
            }
        }
    </script>
</head>
<body>
    <header>
        <h1>WebDAV控制台</h1>
    </header>
    <section>
        <div id="loginBox">
            <label for="pwdInput">请输入访问密码</label>
            <input id="pwdInput" type="password" onkeydown="if(event.key==='Enter'){document.getElementById('loginBtn').click();}" />
            <button id="loginBtn" onclick='
    sessionStorage.setItem("webdav_pwd", document.getElementById("pwdInput").value);
    login();
'>登录</button>
            <p id="loginRes"></p>
        </div>
        <div id="controlBox" style="display:none;">
            <button id="oneKeyBtn" onclick="oneKeySet()">一键设置</button>
            <label for="dirInput">请选择webdav的根目录</label>
            <input id="dirInput" type="text" onkeydown="if(event.key==='Enter'){document.getElementById('dirBtn').click();}" />
            <button id="dirBtn" onclick='submit()'>提交</button>
            <p id="submitRes"></p>
            <hr>
            <label for="webdavUserInput">设置WebDAV用户名</label>
            <input id="webdavUserInput" type="text" onkeydown="if(event.key==='Enter'){document.getElementById('webdavUserBtn').click();}" />
            <button id="webdavUserBtn" onclick='setWebdavUser()'>设置</button>
            <p id="setWebdavUserRes"></p>
            <hr>
            <label for="webdavPwdInput">设置WebDAV密码</label>
            <input id="webdavPwdInput" type="text" onkeydown="if(event.key==='Enter'){document.getElementById('webdavPwdBtn').click();}" />
            <button id="webdavPwdBtn" onclick='setWebdavPwd()'>设置</button>
            <p id="setWebdavPwdRes"></p>
            <hr>
            <label for="consolePwdInput">设置控制台密码</label>
            <input id="consolePwdInput" type="text" onkeydown="if(event.key==='Enter'){document.getElementById('consolePwdBtn').click();}" />
            <button id="consolePwdBtn" onclick='setConsolePwd()'>设置</button>
            <p id="setConsolePwdRes"></p>
        </div>
    </section>
</body>
</html>
            `)
    })

    // 登录接口
    http.HandleFunc("/webdav/control/login", func(resp http.ResponseWriter, req *http.Request) {
        body, err := io.ReadAll(req.Body)
        if err != nil {
            resp.WriteHeader(http.StatusBadRequest)
            json.NewEncoder(resp).Encode(map[string]string{"res": "请求错误"})
            return
        }
        var data struct {
            Password string `json:"password"`
        }
        if err := json.Unmarshal(body, &data); err != nil {
            resp.WriteHeader(http.StatusBadRequest)
            json.NewEncoder(resp).Encode(map[string]string{"res": "请求错误"})
            return
        }
        if data.Password == password {
            json.NewEncoder(resp).Encode(map[string]string{"res": "ok"})
        } else {
            json.NewEncoder(resp).Encode(map[string]string{"res": "密码错误"})
        }
    })

    // 获取当前目录
    http.HandleFunc("/webdav/control/getDir", func(resp http.ResponseWriter, req *http.Request) {
        if req.Header.Get("X-Auth") != password {
            renderUnauthorizedPage(resp)
            return
        }
        resp.Header().Set("Content-Type", "application/json")
        json.NewEncoder(resp).Encode(map[string]string{"res": currentDir})
    })

    // 设置目录
    http.HandleFunc("/webdav/control/setDir", func(resp http.ResponseWriter, req *http.Request) {
        if req.Header.Get("X-Auth") != password {
            renderUnauthorizedPage(resp)
            return
        }
        if req.Method != "POST" {
            renderErrorPage(resp, "不允许直接访问这个页面", http.StatusForbidden)
            return
        }
        body, err := io.ReadAll(req.Body)
        if err != nil {
            renderErrorPage(resp, "错误的请求", http.StatusForbidden)
            return
        }
        var data struct {
            Dir string `json:"dir"`
        }
        if err := json.Unmarshal(body, &data); err != nil {
            renderErrorPage(resp, "错误的请求", http.StatusForbidden)
            return
        }
        if data.Dir == "" {
            resp.Header().Set("Content-Type", "application/json")
            json.NewEncoder(resp).Encode(map[string]string{"res": "目录不能为空"})
            return
        }
        currentDir = data.Dir
        resp.Header().Set("Content-Type", "application/json")
        json.NewEncoder(resp).Encode(map[string]string{"res": "设置成功"})
    })

    // 获取WebDAV用户名
    http.HandleFunc("/webdav/control/getWebdavUser", func(resp http.ResponseWriter, req *http.Request) {
        if req.Header.Get("X-Auth") != password {
            renderUnauthorizedPage(resp)
            return
        }
        resp.Header().Set("Content-Type", "application/json")
        json.NewEncoder(resp).Encode(map[string]string{"res": webdavUser})
    })

    // 设置WebDAV用户名
    http.HandleFunc("/webdav/control/setWebdavUser", func(resp http.ResponseWriter, req *http.Request) {
        if req.Header.Get("X-Auth") != password {
            renderUnauthorizedPage(resp)
            return
        }
        if req.Method != "POST" {
            renderErrorPage(resp, "不允许直接访问这个页面", http.StatusForbidden)
            return
        }
        body, err := io.ReadAll(req.Body)
        if err != nil {
            renderErrorPage(resp, "错误的请求", http.StatusForbidden)
            return
        }
        var data struct {
            User string `json:"user"`
        }
        if err := json.Unmarshal(body, &data); err != nil {
            renderErrorPage(resp, "错误的请求", http.StatusForbidden)
            return
        }
        if data.User == "" {
            resp.Header().Set("Content-Type", "application/json")
            json.NewEncoder(resp).Encode(map[string]string{"res": "WebDAV用户名不能为空"})
            return
        }
        webdavUser = data.User
        resp.Header().Set("Content-Type", "application/json")
        json.NewEncoder(resp).Encode(map[string]string{"res": "WebDAV用户名设置成功"})
    })

    // 获取WebDAV密码
    http.HandleFunc("/webdav/control/getWebdavPwd", func(resp http.ResponseWriter, req *http.Request) {
        if req.Header.Get("X-Auth") != password {
            renderUnauthorizedPage(resp)
            return
        }
        resp.Header().Set("Content-Type", "application/json")
        json.NewEncoder(resp).Encode(map[string]string{"res": webdavPassword})
    })

    // 设置WebDAV密码
    http.HandleFunc("/webdav/control/setWebdavPwd", func(resp http.ResponseWriter, req *http.Request) {
        if req.Header.Get("X-Auth") != password {
            renderUnauthorizedPage(resp)
            return
        }
        if req.Method != "POST" {
            renderErrorPage(resp, "不允许直接访问这个页面", http.StatusForbidden)
            return
        }
        body, err := io.ReadAll(req.Body)
        if err != nil {
            renderErrorPage(resp, "错误的请求", http.StatusForbidden)
            return
        }
        var data struct {
            Password string `json:"password"`
        }
        if err := json.Unmarshal(body, &data); err != nil {
            renderErrorPage(resp, "错误的请求", http.StatusForbidden)
            return
        }
        if data.Password == "" {
            resp.Header().Set("Content-Type", "application/json")
            json.NewEncoder(resp).Encode(map[string]string{"res": "WebDAV密码不能为空"})
            return
        }
        webdavPassword = data.Password
        resp.Header().Set("Content-Type", "application/json")
        json.NewEncoder(resp).Encode(map[string]string{"res": "WebDAV密码设置成功"})
    })

    // 获取控制台密码
    http.HandleFunc("/webdav/control/getConsolePwd", func(resp http.ResponseWriter, req *http.Request) {
        if req.Header.Get("X-Auth") != password {
            renderUnauthorizedPage(resp)
            return
        }
        resp.Header().Set("Content-Type", "application/json")
        json.NewEncoder(resp).Encode(map[string]string{"res": password})
    })

    // 设置控制台密码
    http.HandleFunc("/webdav/control/setConsolePwd", func(resp http.ResponseWriter, req *http.Request) {
        if req.Header.Get("X-Auth") != password {
            renderUnauthorizedPage(resp)
            return
        }
        if req.Method != "POST" {
            renderErrorPage(resp, "不允许直接访问这个页面", http.StatusForbidden)
            return
        }
        body, err := io.ReadAll(req.Body)
        if err != nil {
            renderErrorPage(resp, "错误的请求", http.StatusForbidden)
            return
        }
        var data struct {
            Password string `json:"password"`
        }
        if err := json.Unmarshal(body, &data); err != nil {
            renderErrorPage(resp, "错误的请求", http.StatusForbidden)
            return
        }
        if data.Password == "" {
            resp.Header().Set("Content-Type", "application/json")
            json.NewEncoder(resp).Encode(map[string]string{"res": "控制台密码不能为空"})
            return
        }
        password = data.Password
        resp.Header().Set("Content-Type", "application/json")
        json.NewEncoder(resp).Encode(map[string]string{"res": "控制台密码设置成功"})
    })

    // WebDAV服务
    http.HandleFunc("/webdav/", func(w http.ResponseWriter, r *http.Request) {
        // 简单鉴权：使用 webdavUser 和 webdavPassword
        user, pass, ok := r.BasicAuth()
        if !ok || user != webdavUser || pass != webdavPassword {
            w.Header().Set("WWW-Authenticate", `Basic realm="WebDAV"`)
            w.WriteHeader(http.StatusUnauthorized)
            w.Write([]byte("Unauthorized"))
            return
        }
        handler := &webdav.Handler{
            Prefix:     "/webdav/",
            FileSystem: webdav.Dir(currentDir),
            LockSystem: webdav.NewMemLS(),
        }
        handler.ServeHTTP(w, r)
    })

    http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", port), nil)
}

func renderErrorPage(w http.ResponseWriter, msg string, code int) {
    w.Header().Set("Content-Type", "text/html; charset=utf-8")
    w.WriteHeader(code)
    html := `
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>错误 %d</title>
    <style>
        body {
            background: linear-gradient(135deg, #e0e7ff 0%%, #f4f4f4 100%%);
            font-family: "Segoe UI", "Helvetica Neue", Arial, "Liberation Sans", sans-serif;
            margin: 0;
            padding: 0;
            min-height: 100vh;
        }
        .container {
            max-width: 420px;
            margin: 8vh auto;
            background: #fff;
            border-radius: 14px;
            box-shadow: 0 6px 32px #0002;
            padding: 2.5rem 2rem 2rem 2rem;
            text-align: center;
        }
        h1 {
            font-size: 2.5rem;
            color: #4078c0;
            margin-bottom: 1rem;
        }
        p {
            font-size: 1.15rem;
            color: #444;
            margin-bottom: 2rem;
        }
        a {
            display: inline-block;
            margin-top: 1.5rem;
            color: #fff;
            background: #4078c0;
            padding: 0.7rem 2rem;
            border-radius: 6px;
            text-decoration: none;
            font-weight: 600;
            transition: background 0.18s;
        }
        a:hover {
            background: #305a8d;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>错误 %d</h1>
        <p>%s</p>
    </div>
</body>
</html>`
    html = fmt.Sprintf(html, code, code, msg)
    w.Write([]byte(html))
}

func renderUnauthorizedPage(w http.ResponseWriter) {
    w.Header().Set("Content-Type", "text/html; charset=utf-8")
    w.WriteHeader(http.StatusUnauthorized)
    html := `
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>未授权访问</title>
    <style>
        body {
            background: linear-gradient(135deg, #f8d7da 0%%, #f4f4f4 100%%);
            font-family: "Segoe UI", "Helvetica Neue", Arial, "Liberation Sans", sans-serif;
            margin: 0;
            padding: 0;
            min-height: 100vh;
        }
        .container {
            max-width: 420px;
            margin: 10vh auto;
            background: #fff;
            border-radius: 14px;
            box-shadow: 0 6px 32px #0002;
            padding: 2.5rem 2rem 2rem 2rem;
            text-align: center;
        }
        h1 {
            font-size: 2.2rem;
            color: #c82333;
            margin-bottom: 1rem;
        }
        p {
            font-size: 1.1rem;
            color: #444;
            margin-bottom: 2rem;
        }
        a {
            display: inline-block;
            margin-top: 1.5rem;
            color: #fff;
            background: #c82333;
            padding: 0.7rem 2rem;
            border-radius: 6px;
            text-decoration: none;
            font-weight: 600;
            transition: background 0.18s;
        }
        a:hover {
            background: #a71d2a;
        }
        .icon {
            font-size: 3.5rem;
            margin-bottom: 1rem;
            color: #c82333;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="icon">⛔</div>
        <h1>未授权访问</h1>
        <p>您没有权限访问此页面，请返回登录并输入正确的密码。</p>
        <a href="/webdav/control">返回登录</a>
    </div>
</body>
</html>`
    w.Write([]byte(html))
}